#include "umlclassdiagramm.h"

UmlClassDiagramm::UmlClassDiagramm()
{
    // setting project type
    this->_type = UmlProject::ClassDiagramm;

    this->_itemUnderMouse = 0;

    this->_itemAcceptsDrop = false;
}

void UmlClassDiagramm::initToolbar(QToolBar *toolbar)
{
    QAction *a;

    a = toolbar->addAction(QIcon(":/icons/classdiagramm/toolbar/inheritance.png"), tr("draw inheritance"));
    a->setToolTip(tr("draw a new inheritance relation"));
    QObject::connect(a, SIGNAL(triggered()), this, SLOT(drawInheritanceRelation()));

    a = toolbar->addAction(QIcon(":/icons/classdiagramm/toolbar/implementation.png"), tr("draw implementation"));
    a->setToolTip(tr("draw a new implementation relation"));
    QObject::connect(a, SIGNAL(triggered()), this, SLOT(drawImplementationRelation()));
}

QString UmlClassDiagramm::findAvailableTypeName(QString label)
{
    int i = 1;
    QString newLabel = label;

    while (this->_dataTypes->containsLabel(newLabel)) {
        newLabel = QString("%1_%2").arg(label).arg(i++);
    }

    return newLabel;
}

void UmlClassDiagramm::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{    
    if (event->mimeData()->text() == "add_classitem" ||
        event->mimeData()->text() == "add_abstract_classitem" ||
        event->mimeData()->text() == "add_interface" ||
        event->mimeData()->text() == "add_package") {
        event->accept();
    } else {
        event->ignore();
    }
}

void UmlClassDiagramm::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
{
    if (event->mimeData()->text() == "add_classitem" ||
        event->mimeData()->text() == "add_abstract_classitem" ||
        event->mimeData()->text() == "add_interface" ||
        event->mimeData()->text() == "add_package") {
        event->accept();
    } else {
        event->ignore();
    }
}

void UmlClassDiagramm::dropEvent(QGraphicsSceneDragDropEvent *event)
{
    if (event->mimeData()->text() == "add_classitem") {

        QString name = this->findAvailableTypeName(tr("NewClass"));

        UmlClassItem * item = new UmlClassItem(this);
        item->setText(name);
        item->setPos(event->scenePos());

        this->_dataTypes->insert(name, name, false);

        this->addUmlitem(this->_currentDir, item);

        event->accept();
    }

    else if (event->mimeData()->text() == "add_abstract_classitem") {

        QString name = this->findAvailableTypeName(tr("NewAbstractClass"));

        UmlClassItem * item = new UmlClassItem(this);
        item->setText(name);
        item->setPos(event->scenePos());
        item->setIsAbstract(true);

        this->_dataTypes->insert(name, name, false);

        this->addUmlitem(this->_currentDir, item);

        event->accept();
    }

    else if (event->mimeData()->text() == "add_interface") {

        QString name = this->findAvailableTypeName(tr("NewInterface"));

        UmlClassItem * item = new UmlClassItem(this);
        item->setText(name);
        item->setPos(event->scenePos());
        item->setIsInterface(true);

        this->_dataTypes->insert(name, name, false);

        this->addUmlitem(this->_currentDir, item);

        event->accept();
    }

    else if (event->mimeData()->text() == "add_package") {
        UmlDirItem *dir = new UmlDirItem(this);
        dir->setText(tr("NewPackage"));
        dir->setPos(event->scenePos());
        dir->setParentDir(this->_currentDir);

        this->addUmlitem(this->_currentDir, dir);

        event->accept();
    }

    else {
        event->ignore();
    }

}

void UmlClassDiagramm::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    UmlProject::mouseMoveEvent(event);

    if (this->_isPressed && this->_draggedRelation) {
        UmlRelationalItem *item = dynamic_cast<UmlRelationalItem*>(this->itemUnderMouse(event->scenePos()));

        if (this->_itemUnderMouse != item) {

            if (item) {
                this->_itemAcceptsDrop = item->checkRelation(this->_draggedRelation->relation(), this->_draggedRelation->startItem());
            } else {
                UmlRelationalItem *relationItem = dynamic_cast<UmlRelationalItem*>(this->_itemUnderMouse);
                this->_itemAcceptsDrop = relationItem->checkRelation(0, 0);
            }

        }

        this->_itemUnderMouse = item;
    }
}

void UmlClassDiagramm::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if (this->_draggedRelation && this->_itemUnderMouse) {
        UmlRelation *relation = this->_draggedRelation->relation();
        if (this->_itemAcceptsDrop) {
            relation->setItems(this->_draggedRelation->startItem(), dynamic_cast<UmlRelationalItem*>(this->_itemUnderMouse));
            this->_itemUnderMouse->setGraphicsEffect(0);
            this->_itemAcceptsDrop = false;
        }
    }

    UmlProject::mouseReleaseEvent(event);
}

QDockWidget* UmlClassDiagramm::itemDock()
{
    return new ClassDiagrammDock();
}
